#include "bsp_esp8266_test.h"
#include "bsp_esp8266.h"
#include "./dwt_delay/core_delay.h"
#include <stdio.h>  
#include <string.h>  
#include <stdbool.h>
#include "bsp_dht11.h"
#include "bsp_led.h"
#include "bsp_usart.h"
#include "bsp_oled.h"
#include "stm32f10x_iwdg.h"

#define LED_CMD_NUMBER   8
char *ledCmd[8] = { "LED_RED","LED_GREEN","LED_BLUE","LED_YELLOW","LED_PURPLE","LED_CYAN","LED_WHITE","LED_RGBOFF" };

DHT11_Data_TypeDef DHT11_Data;

volatile uint8_t ucTcpClosedFlag = 0;


/**
  * @brief  获取命令控制数字和使用的数组字符串信息
  * @param  无
  * @retval 无
  */
void Get_ESP82666_Cmd( char * cmd)
{
	uint8_t i;
	char displayCmd[32] = {0};  // 增加缓冲区大小，用于显示的字符串
	uint8_t cmdLen = 0;
	uint8_t displayLen = 0;
	
	// 计算cmd字符串长度
	cmdLen = strlen(cmd);
	if(cmdLen > 100) cmdLen = 100;  // 防止过长
	
	// 查找LED命令（先进行命令匹配，避免数据被修改）
	for(i = 0;i < LED_CMD_NUMBER; i++)
	{
     if(( bool ) strstr ( cmd, ledCmd[i] ))
		 break;
	}
	
	// 提取可打印字符用于显示（在命令匹配之后进行）
	for(uint8_t j = 0; j < cmdLen && displayLen < 30; j++)
	{
		if(cmd[j] >= 0x20 && cmd[j] <= 0x7E)  // 可打印ASCII字符
		{
			displayCmd[displayLen++] = cmd[j];
		}
	}
	displayCmd[displayLen] = '\0';  // 确保字符串结束
	
	// 调试输出 - 显示实际接收到的可打印字符
	printf("Received: %s\r\n", displayCmd);
	
	// OLED显示
	OLED_ClearLine(4);               // 清除第4行
	if(i < LED_CMD_NUMBER)
	{
		OLED_ShowString(4, 1, ledCmd[i]);  // 显示匹配的LED命令
	}
	else if(displayLen > 0)
	{
		OLED_ShowString(4, 1, displayCmd);  // 显示过滤后的命令
	}
	else
	{
		OLED_ShowString(4, 1, "NO_CMD");    // 显示无有效命令
	}
	
	switch(i)
    {
      case 0:
        LED_RED;
      break;
      case 1:
        LED_GREEN;
      break;
      case 2:
        LED_BLUE;
      break;
      case 3:
        LED_YELLOW;
      break;
      case 4:
        LED_PURPLE;
      break;
      case 5:
        LED_CYAN;
      break;
      case 6:
        LED_WHITE;
      break;
      case 7:
        LED_RGBOFF;
      break;
      default:
        
        break;      
    }   
}


/**
  * @brief  ESP8266 StaTcpClient Unvarnish 配置测试函数
  * @param  无
  * @retval 无
  */
void ESP8266_StaTcpClient_Unvarnish_ConfigTest(void)
{
  printf( "\r\n正在配置 ESP8266 ......\r\n" );
  printf( "\r\n使能 ESP8266 ......\r\n" );
	macESP8266_CH_ENABLE();
	//AT
	while( ! ESP8266_AT_Test() ) 
	{
		IWDG_ReloadCounter();  // 喂狗
	}
	//AT+CWDHCP_CUR=1,1 设置ESP8266 Station模式下开启DHCP
  while( ! ESP8266_DHCP_CUR () )
	{
		IWDG_ReloadCounter();  // 喂狗
	}
  printf( "\r\n正在配置工作模式 STA ......\r\n" );
	//AT+CWMODE=1 设置为 station 模式
	while( ! ESP8266_Net_Mode_Choose ( STA ) )
	{
		IWDG_ReloadCounter();  // 喂狗
	}

  printf( "\r\n正在连接 WiFi ......\r\n" );
	//AT+CWJAP="SSID","password"连接指定路由器
  while( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) )
	{
		IWDG_ReloadCounter();  // 喂狗，WiFi连接可能耗时较长
	}
	
  printf( "\r\n禁止多连接 ......\r\n" );
	//AT+CIPMUX=0 TCP单连接
	while( ! ESP8266_Enable_MultipleId ( DISABLE ) )
	{
		IWDG_ReloadCounter();  // 喂狗
	}
	
  printf( "\r\n正在连接 Server ......\r\n" );
	//AT+CIPSTART="TCP","192.168.1.11",8000 建立 TCP 连接、UDP 传输或 SSL 连接
	while( !	ESP8266_Link_Server ( enumTCP, macUser_ESP8266_TcpServer_IP, macUser_ESP8266_TcpServer_Port, Single_ID_0 ) )
	{
		IWDG_ReloadCounter();  // 喂狗，服务器连接可能耗时较长
	}
	
  printf( "\r\n进入透传发送模式 ......\r\n" );
	//1、AT+CIPMODE=1 设置传输模式为透传
	//2、AT+CIPSEND 开始透传发送
	while( ! ESP8266_UnvarnishSend () )
	{
		IWDG_ReloadCounter();  // 喂狗
	}
	
	printf( "\r\n配置 ESP8266 完毕\r\n" );
  
}


/**
  * @brief  ESP8266 发送DHT11数据测试函数
  * @param  无
  * @retval 无
  */
void ESP8266_SendDHT11DataTest(void)
{
  char cStr [ 100 ] = { 0 };
  uint8_t ucStatus;
  
  if( 1 == read_dht11_finish )
    sprintf ( cStr, "\r\n\r\n读取DHT11成功!\r\n湿度为%d.%d %%RH ，温度为 %d.%d℃ \r\n", 
              DHT11_Data.humi_int, DHT11_Data.humi_deci, DHT11_Data.temp_int, DHT11_Data.temp_deci );
  else
		sprintf ( cStr, "Read DHT11 ERROR!\r\n" );
  
  printf ( "%s", cStr );                                             //打印读取 DHT11 温湿度信息

  ESP8266_SendString ( ENABLE, cStr, 0, Single_ID_0 );               //发送 DHT11 温湿度信息到网络调试助手
  
  
  if ( ucTcpClosedFlag )                                             //检查是否失去连接
  {
    ESP8266_ExitUnvarnishSend ();                                    //退出透传模式
    
    do 
    {
      ucStatus = ESP8266_Get_LinkStatus ();                         //获取连接状态
      IWDG_ReloadCounter();  // 喂狗
    }
    while ( ! ucStatus );
    
    if ( ucStatus == 4 )                                             //确认失去连接后重连
    {
      printf ( "\r\n正在重连热点和服务器 ......\r\n" );
      
      while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) )
      {
        IWDG_ReloadCounter();  // 喂狗，重连WiFi可能耗时较长
      }
      
      while ( !	ESP8266_Link_Server ( enumTCP, macUser_ESP8266_TcpServer_IP, macUser_ESP8266_TcpServer_Port, Single_ID_0 ) )
      {
        IWDG_ReloadCounter();  // 喂狗，重连服务器可能耗时较长
      }
      
      printf ( "\r\n重连热点和服务器成功\r\n" );

    }
    
    while ( ! ESP8266_UnvarnishSend () )
    {
      IWDG_ReloadCounter();  // 喂狗
    }		
    
  }
}


/**
  * @brief  ESP8266 检查是否接收到数据，处理连接和灯光控制
  * @param  无
  * @retval 无
  */
void ESP8266_CheckRecvDataTest(void)
{
  uint8_t ucStatus;
  uint16_t i;
  
  /* 处理接收到串口的数据并发送到网络 */
  if(strUSART_Fram_Record.InfBit.FramFinishFlag == 1)
  {
    // 先添加字符串结束符，确保数据完整性
    strUSART_Fram_Record.Data_RX_BUF[strUSART_Fram_Record.InfBit.FramLength] = '\0';
    
    // 先处理命令，再转发数据
    Get_ESP82666_Cmd(strUSART_Fram_Record .Data_RX_BUF);                         //检查一下是不是灯控命令
    
    for(i = 0;i < strUSART_Fram_Record.InfBit.FramLength; i++)
    {
       USART_SendData( macESP8266_USARTx ,strUSART_Fram_Record.Data_RX_BUF[i]); //转发到ESP8266
       while(USART_GetFlagStatus(macESP8266_USARTx,USART_FLAG_TC)==RESET){}      //等待发送完成
    }
    
    strUSART_Fram_Record .InfBit .FramLength = 0;                                //清除数据长度标志
    strUSART_Fram_Record .InfBit .FramFinishFlag = 0;                            //清除接收标志
  }
  
  /* 处理接收到ESP8266的数据 */
  if(strEsp8266_Fram_Record.InfBit.FramFinishFlag)
  {                                                      
    // 先添加字符串结束符，确保数据完整性
    strEsp8266_Fram_Record.Data_RX_BUF[strEsp8266_Fram_Record.InfBit.FramLength] = '\0';
    
    // 先处理命令，再转发数据
    Get_ESP82666_Cmd(strEsp8266_Fram_Record .Data_RX_BUF);                      //检查一下是不是灯控命令
    
    for(i = 0;i < strEsp8266_Fram_Record .InfBit .FramLength; i++)               
    {
       USART_SendData( DEBUG_USARTx ,strEsp8266_Fram_Record .Data_RX_BUF[i]);    //转发到调试串口
       while(USART_GetFlagStatus(DEBUG_USARTx,USART_FLAG_TC)==RESET){}
    }
    
     strEsp8266_Fram_Record .InfBit .FramLength = 0;                             //清除数据长度标志
     strEsp8266_Fram_Record.InfBit.FramFinishFlag = 0;                           //清除接收标志
  }
  
  if ( ucTcpClosedFlag )                                             //检查是否失去连接
  {
    ESP8266_ExitUnvarnishSend ();                                    //退出透传模式
    
    do ucStatus = ESP8266_Get_LinkStatus ();                         //获取连接状态
    while ( ! ucStatus );
    
    if ( ucStatus == 4 )                                             //确认失去连接后重连
    {
      printf ( "\r\n正在重连热点和服务器 ......\r\n" );
      
      while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) );
      
      while ( !	ESP8266_Link_Server ( enumTCP, macUser_ESP8266_TcpServer_IP, macUser_ESP8266_TcpServer_Port, Single_ID_0 ) );
      
      printf ( "\r\n重连热点和服务器成功\r\n" );

    }
    
    while ( ! ESP8266_UnvarnishSend () );		
    
  }
}
